package com.unitd.frame.sso.common.token;

import com.unitd.frame.sso.common.config.SSOConfig;
import com.unitd.frame.sso.common.helper.IpHelper;
import com.unitd.frame.comm.utils.encrypt.RSA;
import com.unitd.frame.comm.utils.RandomUtil;
import com.unitd.frame.sso.exception.SsoException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;

/**
 * @desc SSO 跨域信任Token
 * @filename AuthToken.java
 * @copyright www.unitd.com
 * @author Hudan
 * @version 1.0
 * @date 2016/10/14
 */
@SuppressWarnings("serial")
public class AuthToken extends Token {

	private final Logger logger = LoggerFactory.getLogger(this.getClass().getName());

	private String uuid; 							// 32位的UUID
	private String sign; 							// RAS加密签名串
	private String data; 							// cookie对象信息,作为预留字段暂不使用

	protected AuthToken() {
	}

	/**
	 * @desc 有参构造函数
	 * @param request 请求对象
	 * @param privateKey RSA 私钥(业务系统)
	 */
	public AuthToken(HttpServletRequest request, String privateKey) {
		this.uuid = RandomUtil.get32UUID();
		this.setIp(IpHelper.getIpAddr(request));
		this.sign(privateKey); 									// 设置签名,此签名为RAS加密签名
		this.setApp(SSOConfig.getInstance().getAppName()); 		// 设置当前登陆子系统的角色
	}

	/**
	 * @desc 将当前登陆UUID和IP组合,生成签名字节数组
	 * @return byte[]
	 */
	public byte[] signByte() {
		StringBuilder sb = new StringBuilder();
		sb.append(getUuid()).append("-").append(getIp());
		return sb.toString().getBytes();
	}

	/**
	 * @desc 设置签名,此签名为RAS加密签名
	 * @param privateKey RSA私钥(签名)
	 */
	public void sign(String privateKey) {
		try {
			this.sign = RSA.sign(signByte(), privateKey);
		} catch (Exception e) {
			logger.error("生成RSA私钥签名错误!");
			e.printStackTrace();
			throw new SsoException("生成RSA私钥签名错误!");
		}
	}

	/**
	 * @desc 验证AuthToken的签名是否合法
	 * @param publicKey RSA公钥(验证签名)
	 * @return 授权签名的合法性
	 */
	public AuthToken verify(String publicKey) {
		try {
			// RSA 验证摘要 是否合法
			if (RSA.verify(signByte(), publicKey, getSign())) {
				return this;
			}
		} catch (Exception e) {
			logger.error("验证AuthToken的签名失败["+e.getMessage()+"]");
			e.printStackTrace();
			throw new SsoException("验证AuthToken的签名失败["+e.getMessage()+"]");
		}
		return null;
	}

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}
}